/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2021 Huawei Technologies Co., Ltd */

#ifndef HINIC3_IPSEC_H
#define HINIC3_IPSEC_H

#include "hinic3_nic_dev.h"

#define HINIC3_IPSEC_SADB_BITS 16
#define HINIC3_IPSEC_SA_HASH_TBL_SIZE (1 << (HINIC3_IPSEC_SADB_BITS))
#define HINIC3_IPSEC_SP_HASH_TBL_SIZE (1 << (HINIC3_IPSEC_SADB_BITS))

#define HINIC3_IPSEC_TOTAL_SA_CTX_NUM (128 * 1024)
#define HINIC3_IPSEC_PER_PF_SA_CTX_NUM (32 * 1024)
#define HINIC3_IPSEC_SA_CTX_SIZE 512
#define HINIC3_IPSEC_XID_RESERVE_NUM 2

/* esp_tailer = tfc_padding_len + pad_length + 2B(Pad Length Next Header) */
#define HINIC3_IPSEC_ESP_TAILER_FMT_LEN 2

#define HINIC3_IS_IP_IPSEC_OFFLOAD(xs, skb)	\
	(!(xs)->xso.offload_handle ||	\
	((skb)->protocol != htons(ETH_P_IP) &&	\
	 (skb)->protocol != htons(ETH_P_IPV6)))

struct hinic3_ipsec_stats {
	u64 rx_ipsec_packets;
	u64 rx_ipsec_secure_policy_errors;
	u64 rx_ipsec_xfrm_state_errors;
	u64 rx_ipsec_xfrm_offload_errors;

	u64 tx_ipsec_packets;
	u64 tx_ipsec_secure_policy_errors;
	u64 tx_ipsec_xfrm_state_errors;
	u64 tx_ipsec_ip_errors;
	u64 tx_ipsec_tailer_errors;

#ifdef HAVE_NDO_GET_STATS64
	struct u64_stats_sync		syncp;
#else
	struct u64_stats_sync_empty	syncp;
#endif
};

struct hinic3_ipsec_xmap {
	void *sa_ctx;
};

/* IPsec SA Database */
struct hinic3_ipsec {
	struct hinic3_nic_dev *nic_dev;
	struct hlist_head sadb[HINIC3_IPSEC_SA_HASH_TBL_SIZE];
	spinlock_t sadb_lock; /* lock SAD */
	bool no_trailer;
	struct hinic3_ipsec_stats stats;
	struct workqueue_struct *esn_wq;
	struct hinic3_ipsec_xmap *xmap; /* xid map to sa item table */
};

extern unsigned char ipsec_work_mode;
int hinic3_init_ipsec_offload(struct hinic3_nic_dev *nic_dev);
void hinic3_cleanup_ipsec_offload(struct hinic3_nic_dev *nic_dev);

#endif /* _HINIC3_IPSEC_H_ */
